#include <assert.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <string>
#include <curl/curl.h>
#include "cJSON.h"
#include "speechnls.h" 
#include "het_ringbuf.h" 
#include "minimp3.h" 
#include "decode.h"
#include "het_chatgpt.h"

static char ali_tokenBuf[128]={""};
static char ali_appKeyBuf[64]={""};
static char ali_voiceBuf[32]={"xiaoyun"};//声音模型
static int ali_sampleRate=16000;
static int ali_volume=80; 
static int ali_speechRate=0;
static int ali_pitchRate=0;
static long ali_expireTime=0;




/**
 * @brief 设置token
 */
void update_ali_token(char * token){
    strncpy(ali_tokenBuf,token,sizeof(ali_tokenBuf)-1);
    ali_tokenBuf[sizeof(ali_tokenBuf)-1] = '\0';
}
/**
 * @brief 设置appKey
 */
void update_ali_appKey(char * key){
    strncpy(ali_appKeyBuf,key,sizeof(ali_appKeyBuf)-1);
    ali_appKeyBuf[sizeof(ali_appKeyBuf)-1] = '\0';
}
/**
 * @brief 设置声音模型
 */
void update_ali_voice(char * voice){
    strncpy(ali_voiceBuf,voice,sizeof(ali_voiceBuf)-1);
    ali_voiceBuf[sizeof(ali_voiceBuf)-1] = '\0';
}
/**
 * @brief 设置执行超时时间
 */
void update_ali_expireTime(long expireTime){
    ali_expireTime = expireTime;
}
/**
 * @brief 设置音频采样率
 */
void update_ali_sampleRate(int sampleRate){
    ali_sampleRate = sampleRate;
}
/**
 * @brief 设置音频音量
 */
void update_ali_volume(int volume){
    ali_volume = volume;
}
/**
 * @brief 设置音频pitchRate
 */
void update_ali_pitchRate(int pitchRate){
    ali_pitchRate = pitchRate;
}
/**
 * @brief 设置音频speechRate
 */
void update_ali_speechRate(int speechRate){
    ali_speechRate = speechRate;
}
// 全局标点符号数组
const char *punctuations[] = {
    "，", "。", "？", "！", "；","：",  // Chinese
    ".", "?", "!", ";",          // English
    "、", "。", "？", "！",        // Japanese
    ".", "?", "!", ";",          // French
    "،", "؟",                     // Arabic
    ".", "?", "!", ";",          // Portuguese
    ".", "?", "!", ";",          // Spanish
    ".", "?", "!", ";",          // German
    NULL
};

// 判断字符是否为标点符号，返回标点符号的位置和长度
int find_punctuation(const char *str, int *punct_pos) {
    for (int i = 0; punctuations[i] != NULL; i++) {
        int len = strlen(punctuations[i]);
        if (strncmp(str, punctuations[i], len) == 0) {
            *punct_pos = len;
            return 1;
        }
    }
    return 0;
}

// 计算一个字符串中的字符数或单词数
int count_words_or_characters(const char *str) {
    int count = 0;
    while (*str != '\0') {
        if ((*str & 0x80) == 0) {
            // 处理ASCII字符（假设ASCII字符表示单词之间的分隔符）
            if (*str != ' ' && *str != '\t' && *str != '\n') {
                count++;
                while (*str != ' ' && *str != '\t' && *str != '\n' && *str != '\0') {
                    str++;
                }
            }
        } else {
            // 处理非ASCII字符（如中文字符）
            count++;
            // 跳过UTF-8字符（每个UTF-8字符占用1-4个字节）
            if ((*str & 0xE0) == 0xC0) {
                str += 1;
            } else if ((*str & 0xF0) == 0xE0) {
                str += 2;
            } else if ((*str & 0xF8) == 0xF0) {
                str += 3;
            }
        }
        str++;
    }
    return count;
}

// 假设性的函数，用于将字符编码为URL格式（简化版，不考虑完整的UTF-8处理）  
void simple_url_encode_char(unsigned char c, char *output) {  
    static const char hex_digits[] = "0123456789ABCDEF";  
    if (isalnum(c) || strchr("-_.~", c) != NULL) {  
        // 如果是URL安全的字符，则直接输出  
        *output = c;  
        output[1] = '\0';  
    } else {  
        // 需要编码的字符  
        output[0] = '%';  
        output[1] = hex_digits[(c >> 4) & 0xF];  
        output[2] = hex_digits[c & 0xF];  
        output[3] = '\0';  
    }  
}  
// 简化的URL编码函数，处理包含中文和特殊字符的字符串（但不完整处理UTF-8）  
void simple_url_encode(const char *input, char *output, size_t output_size) {  
    const char *in_ptr = input;  
    char *out_ptr = output;  
    size_t remaining = output_size - 1; // 保留一个字节给null终止符  
  
    while (*in_ptr && remaining > 0) {  
        unsigned char c = (unsigned char)*in_ptr++;  
        char encoded_char[4]; // 足够存储一个编码后的字符（包括'\0'）  
        simple_url_encode_char(c, encoded_char);  
  
        // 复制编码后的字符到输出字符串  
        size_t len = strlen(encoded_char);  
        if (remaining < len) break; // 防止缓冲区溢出  
        strcpy(out_ptr, encoded_char);  
        out_ptr += len;  
        remaining -= len;  
  
        // 注意：这里没有处理UTF-8多字节字符的完整性  
        // 在实际应用中，你需要使用能够处理UTF-8的库  
    }  
  
    *out_ptr = '\0'; // 确保字符串以null终止  
}
uint32_t s32ChnId=0;
// 回调函数，处理服务器响应

void save_file(char * data,int len){
    FILE *fp = RK_NULL;
    char name[256];
    snprintf(name, sizeof(name), "/userdata/ai_loali_%d.wav", s32ChnId++);
    fp = fopen(name, "wb");
    if (fp != RK_NULL) {
        fwrite(data, 1, len, fp);
        fflush(fp);
        fclose(fp);
    }
}
size_t audioPlayBuf_write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) {
    // 这里可以处理服务器返回的数据，但WebSocket连接通常不需要处理HTTP响应体
    if(in_play){
        //HET_LOGI("wc %d\r\n",size * nmemb);
        rb_push(&audioPlayBuf,ptr,size * nmemb);
    }
    return size * nmemb;
}
struct mp3DecoderCurlBuf{
    mp3dec_t pstMp3Decoder;
    uint16_t mp3BufSize;// 已解码数据长度
    uint8_t u8PcmBuf[MINIMP3_MAX_SAMPLES_PER_FRAME];
    uint8_t u8Mp3Buf[2*6*1024];
};
size_t mp3Buf_write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) {
    // 这里可以处理服务器返回的数据，但WebSocket连接通常不需要处理HTTP响应体
    // 定义变量
    int32_t s32Ret = 1;		// MP3组合数据长度
    int32_t s32RetLen = 1;		// MP3组合数据剩余长度
    int32_t s32FillLen = 1;		// MP3组合数据剩余长度

    uint32_t u32Mp3DataPos = 0;		// MP3剩余数据长度
    uint32_t u32Mp3DataLen = 0;		// MP3剩余数据长度
    uint32_t u32PcmDataPos = 0;		// Pcm位置
    int32_t s32Mp3DecAllDataLen = 0;	// 当前组合BUF中，MP3已解码的数据长度
    uint32_t u32Mp3FileOnceReadLen = 6*1024;	// 一次性解码6kB数据
    uint32_t u32DevOncePlayPcmLen = 1024;	// 一次性填充的PCM数据长度
    mp3dec_frame_info_t stMp3DecFrameInfo;	// 一帧MP3解码出来的PCM帧信息
    struct mp3DecoderCurlBuf* pCurlBuf = (struct mp3DecoderCurlBuf*)userdata;
    uint32_t u32PcmSamples = 0;
    int s32Cnt;
    if(in_play && pCurlBuf){
        /**
        * 
        *mp3dec_t *dec   //解码器信息，由mp3dec_t结构体定义
        *const uint8_t *mp3	// MP3数据缓冲区头地址
        *int mp3_bytes	// MP3缓冲区，未解码的数据长度
        *mp3d_sample_t *pcm	// PCM缓冲区地址，默认short型
        *mp3dec_frame_info_t *info	// 解码出来的一帧PCM数据信息，包括帧长、通道数、频率、比特率等信息
        */
        //int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info)

        uint32_t u32PcmSamples = 0, u32RemainSamples=0;		// PCM原始长度变量和PCM剩余长度变量
        
        s32RetLen = nmemb * size;
        while(s32RetLen){
            //HET_LOGI("s32RetLen:%d\r\n",s32RetLen);
            //获取要填充的长度
            u32Mp3DataLen = sizeof(pCurlBuf->u8Mp3Buf) - pCurlBuf->mp3BufSize;
            //要拷贝的长度
            s32FillLen= (s32RetLen)>u32Mp3DataLen?u32Mp3DataLen:s32RetLen;
            //拷贝缓存
            memcpy(pCurlBuf->u8Mp3Buf + pCurlBuf->mp3BufSize, ptr+(nmemb * size-s32RetLen), s32FillLen);
            //更新未拷贝长度
            s32RetLen -= s32FillLen;
        
            s32Mp3DecAllDataLen = 0;
            s32Ret = s32FillLen + pCurlBuf->mp3BufSize;
            do {
                u32PcmSamples = sizeof(int16_t)*mp3dec_decode_frame(&pCurlBuf->pstMp3Decoder, pCurlBuf->u8Mp3Buf + s32Mp3DecAllDataLen, s32Ret - s32Mp3DecAllDataLen, (int16_t*)(pCurlBuf->u8PcmBuf), &stMp3DecFrameInfo);
                //HET_LOGI("channels:%d,frame_bytes:%d,hz:%d,frame_offset:%d\r\n",stMp3DecFrameInfo.channels, stMp3DecFrameInfo.frame_bytes, stMp3DecFrameInfo.hz, stMp3DecFrameInfo.frame_offset);

                //当前解码的BUF数据长度
                u32RemainSamples = u32PcmSamples * stMp3DecFrameInfo.channels;

                //积累已解码的MP3数据长度
                s32Mp3DecAllDataLen += stMp3DecFrameInfo.frame_bytes;

                // PCM填充BUF
                s32Cnt=u32RemainSamples;
                u32PcmDataPos = 0;
                while(s32Cnt)
                {
                    //fwrite(u8PcmBuf + s32Cnt*u32DevOncePlayPcmLen, 1, u32DevOncePlayPcmLen, pcmFile);
                    u32PcmDataPos+=rb_push(&audioPlayBuf,pCurlBuf->u8PcmBuf + u32PcmDataPos, u32RemainSamples-u32PcmDataPos);
                    s32Cnt -= u32PcmDataPos;
                }

                //更新未解码的MP3数据长度
                if(s32Ret - s32Mp3DecAllDataLen < stMp3DecFrameInfo.frame_bytes*2)
                {
                    u32Mp3DataPos = s32Ret - s32Mp3DecAllDataLen;
                    pCurlBuf->mp3BufSize = u32Mp3DataPos;
                    memcpy(pCurlBuf->u8Mp3Buf, pCurlBuf->u8Mp3Buf+s32Mp3DecAllDataLen, u32Mp3DataPos);
                    break;
                }
                else{
                    u32Mp3DataPos = 0;
                }
                //HET_LOGI("u32PcmSamples:%d\r\n",u32PcmSamples);
            }while (u32PcmSamples);
        }
    }
    return size * nmemb;
}

size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) {
    size_t realsize = size * nmemb;
    MemoryStruct *mem = (MemoryStruct *)userdata;

    char *ptr_new = (char *)realloc(mem->data, mem->size + realsize + 1);
    if (ptr_new == NULL) {
        // 内存分配失败
        HET_LOGE("Not enough memory (realloc returned NULL)\r\n");
        return 0;
    }

    mem->data = ptr_new;
    memcpy(&(mem->data[mem->size]), ptr, realsize);
    mem->size += realsize;
    mem->data[mem->size] = 0;

    return realsize;
}

pthread_t sendStreamThread; 
/**
 * @brief 语音合成
 */
int speechSynthesizerPut(char *textStr,char *saveStr){
    char url[8192*2+2048];
    char encoded[8192*2];
    CURL *curl;
    CURLcode res;
    memset(url,0,sizeof(url));
    memset(encoded,0,sizeof(encoded));
    if(!textStr){
        in_tts = RK_FALSE;
        return -2;
    }
    simple_url_encode(textStr, encoded, sizeof(encoded));
    int strLen =snprintf(url,8192*2+2048-1,"https://nls-gateway-cn-shenzhen.aliyuncs.com/stream/v1/tts?appkey=%s&token=%s&text=%s&format=pcm&sample_rate=%d&voice=%s",
    ali_appKeyBuf,ali_tokenBuf,encoded,ali_sampleRate,ali_voiceBuf);
    int seek = 0, sendLen;
    while(strLen){
        HET_LOGI("url:%s\r\n",url+seek);
        sendLen = strLen > MAX_BUF?MAX_BUF:strLen;
        seek += sendLen;
        strLen -= sendLen;
    }

    HET_LOGD("lock\r\n");
    pthread_mutex_lock(&curl_lock);   
    in_tts = RK_TRUE; 
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if(curl) {
        // 设置目标URL
        curl_easy_setopt(curl, CURLOPT_URL, url);

        // 设置HTTP头部，请求Upgrade到WebSocket
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        //临时禁用ssl
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
        //curl_easy_setopt(curl, CURLOPT_CAINFO,"/userdata/curl_cacert.pem");
 
        // 设置连接超时时间
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
        // 设置POST请求
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);

        // 设置请求体
        //const char *data = "{\"appkey\":\"g5LYqJWx9s6iIlYi\",\"text\":\"你好，我来测试下下!!!请播放1,2,3,4,5,6,7\",\"token\":\"\"}";
        //curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);

        // 设置回调函数处理响应
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, audioPlayBuf_write_callback);

        // 创建播放线程
#if 0
        if(!ao_run){
            ao_run = true;
            ali_ctx.ao.dstFilePath = NULL;
            pthread_create(&sendStreamThread, NULL, HET_AO_Play_Stream_Thread, (void *)(&ali_ctx.ao));
        }
#endif
        // 执行请求
        HET_LOGD("play lock\r\n");
        pthread_mutex_lock(&play_lock);
        res = curl_easy_perform(curl);
        pthread_mutex_unlock(&play_lock);
        HET_LOGD("play unlock\r\n");
        // 检查请求是否成功
        if(res != CURLE_OK){
            HET_LOGE("curl_easy_perform() failed: %s\r\n", curl_easy_strerror(res));
        }
        // 清理cURL相关资源
        HET_LOGD("curl_slist_free_all\r\n");
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }else{
        HET_LOGE("curl_easy_init() failed\r\n");
    }
    curl_global_cleanup();
    in_tts = RK_FALSE;
    pthread_mutex_unlock(&curl_lock);
    HET_LOGD("unlock\r\n");
    return 0;
}

/**
 * @brief 语音合成mp3格式
 */
int speechSynthesizerPutMp3(char *textStr){
    char url[8192*2+2048];
    char encoded[8192*2];
    CURL *curl;
    CURLcode res;
    mp3dec_t mp3d;
    memset(url,0,sizeof(url));
    memset(encoded,0,sizeof(encoded));
    if(!textStr){
        in_tts = RK_FALSE;
        return -2;
    }
    struct mp3DecoderCurlBuf* pstMp3Decoder = (struct mp3DecoderCurlBuf*)malloc(sizeof(struct mp3DecoderCurlBuf));
    if(pstMp3Decoder == NULL){
        in_tts = RK_FALSE;
        return -6;
    }
    memset(pstMp3Decoder,0,sizeof(struct mp3DecoderCurlBuf));
    simple_url_encode(textStr, encoded, sizeof(encoded));
    int strLen =snprintf(url,8192*2+2048-1,"https://nls-gateway-cn-shenzhen.aliyuncs.com/stream/v1/tts?appkey=%s&token=%s&text=%s&format=mp3&sample_rate=%d&voice=%s",
    ali_appKeyBuf,ali_tokenBuf,encoded,ali_sampleRate,ali_voiceBuf);
    int seek = 0, sendLen;
    while(strLen){
        HET_LOGI("url:%s\r\n",url+seek);
        sendLen = strLen > MAX_BUF?MAX_BUF:strLen;
        seek += sendLen;
        strLen -= sendLen;
    }
    HET_LOGD("lock\r\n");
    pthread_mutex_lock(&curl_lock);   
    in_tts = RK_TRUE; 
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if(curl) {
        // 设置目标URL
        curl_easy_setopt(curl, CURLOPT_URL, url);

        // 设置HTTP头部，请求Upgrade到WebSocket
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        //临时禁用ssl
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
        //curl_easy_setopt(curl, CURLOPT_CAINFO,"/userdata/curl_cacert.pem");
 
        // 设置连接超时时间
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
        // 设置POST请求
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);

        // 设置请求体
        //const char *data = "{\"appkey\":\"g5LYqJWx9s6iIlYi\",\"text\":\"你好，我来测试下下!!!请播放1,2,3,4,5,6,7\",\"token\":\"\"}";
        //curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);

        // 设置回调函数处理响应
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, mp3Buf_write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)pstMp3Decoder);


        // 执行请求
        HET_LOGD("play lock\r\n");
        pthread_mutex_lock(&play_lock);
        res = curl_easy_perform(curl);
        // 检查请求是否成功
        if(res != CURLE_OK){
            HET_LOGE("curl_easy_perform() failed: %s\r\n", curl_easy_strerror(res));
        }
        //播放MP3
        if(!in_play){

        }
        pthread_mutex_unlock(&play_lock);
        HET_LOGD("play unlock\r\n");
        // 清理cURL相关资源
        HET_LOGD("curl_slist_free_all\r\n");
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }else{
        HET_LOGE("curl_easy_init() failed\r\n");
    }
    curl_global_cleanup();
    in_tts = RK_FALSE;
    pthread_mutex_unlock(&curl_lock);
    
    free(pstMp3Decoder);
    HET_LOGD("unlock\r\n");
    return 0;
}

static char *openai_key = NULL;
static char *openai_url = NULL;
static char *openai_model = NULL;

static int chat_cloud = 0;// 0 表示使用厂商平台，1，表示使用openai平台
void update_chat_cloud(int id){
    chat_cloud = id;
    if(chat_cloud)
        HET_LOGI("change openai!!!\r\n");
    else       
		HET_LOGI("change own!!!\r\n");
}
int get_chat_cloud(void){
    return chat_cloud;
}
void update_openai_key(char * key){
    openai_key = key;
}
void update_openai_url(char * url){
    openai_url = url;
}
void update_openai_model(char * model){
    openai_model = model;
}
void update_openai_clean(void){
    if(openai_key)
        free(openai_key);
    if(openai_url)
        free(openai_key);
    if(openai_model)
        free(openai_key);
    chat_cloud = 0;
}

static char nls_recognizer_buf[8192]={'\0'};//识别出来的文字
/**
 * @brief 获取识别返回结果
 */
char * nls_recognizer_get(void){
    char * ret=NULL;
    pthread_mutex_lock(&curl_buf_lock);
    if(strlen(nls_recognizer_buf) > 1){
        ret = strdup(nls_recognizer_buf);
    };
    pthread_mutex_unlock(&curl_buf_lock);
    if(ret)
        HET_LOGD("get_recognizer_buf %s\r\n",ret);
    return ret;
}
void nls_recognizer_clean(void){
    pthread_mutex_lock(&curl_buf_lock);
    nls_recognizer_buf[0]='\0';
    pthread_mutex_unlock(&curl_buf_lock);
}
static char nls_openai_buf[8192]={'\0'};
/**
 * @brief 获取openAI返回结果
 */
char * nls_openai_get(void){
    char * ret=NULL;
    pthread_mutex_lock(&curl_buf_lock);
    if(strlen(nls_openai_buf) > 1){
        ret = strdup(nls_openai_buf);
    };
    pthread_mutex_unlock(&curl_buf_lock);
    HET_LOGD("get_openai_buf %s\r\n",ret?ret:"is NULL");
    return ret;
}
/** 
 * @brief 请求openai
*/
int openaiPut(char * textStr,int autoGoto){ 
    char url[2048];
    CURL *curl;
    CURLcode res;
    struct curl_slist *headers = NULL;
    char *post_data;
    cJSON *json, *messages, *message;
    MemoryStruct chunk;
    cJSON *content = NULL;
    cJSON *response_json = NULL;
    
    in_query = RK_TRUE;
    chunk.data = (char *)malloc(1);  // 初始内存分配
    chunk.data[0]='\0';
    chunk.size = 0;          // 没有数据

    // 创建JSON请求体
    json = cJSON_CreateObject();
    cJSON_AddStringToObject(json, "model", openai_model);
    messages = cJSON_AddArrayToObject(json, "messages");
    message = cJSON_CreateObject();
    cJSON_AddStringToObject(message, "role", "user");
    cJSON_AddStringToObject(message, "content", textStr);
    cJSON_AddItemToArray(messages, message);
    post_data = cJSON_PrintUnformatted(json);

    HET_LOGD("lock\r\n");
    pthread_mutex_lock(&curl_lock);
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if (curl) {
        // 设置URL
        curl_easy_setopt(curl, CURLOPT_URL, openai_url);

        // 设置HTTP POST请求
        curl_easy_setopt(curl, CURLOPT_POST, 1L);

        // 设置请求头
        headers = curl_slist_append(headers, "Content-Type: application/json");
        char key[128];
        memset(key,0,sizeof(key));
        snprintf(key,sizeof(key),"api-key: %s",openai_key);
        key[sizeof(key)-1] = '\0';
        headers = curl_slist_append(headers, key);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        //临时禁用ssl
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);

        // 设置请求体
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);

        // 设置回调函数处理响应
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

        // 执行请求
        res = curl_easy_perform(curl);

        // 检查请求是否成功
        if (res != CURLE_OK) {
            HET_LOGE("curl_easy_perform() failed: %s\r\n", curl_easy_strerror(res));
        } else {
            // 使用cJSON解析返回的数据
            cJSON *response_json = cJSON_Parse(chunk.data);
            if (response_json == NULL) {
                HET_LOGE("Error parsing JSON response\r\n");
            } else {
                cJSON *choices = cJSON_GetObjectItemCaseSensitive(response_json, "choices");
                if (cJSON_IsArray(choices)) {
                    cJSON *choice = cJSON_GetArrayItem(choices, 0);
                    cJSON *message = cJSON_GetObjectItemCaseSensitive(choice, "message");
                    content = cJSON_GetObjectItemCaseSensitive(message, "content");
                    if (cJSON_IsString(content) && (content->valuestring != NULL)) {
                        HET_LOGI("Response: %s\r\n", content->valuestring);
                    }
                }
            }
        }

        // 清理
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }else{
        HET_LOGE("curl_easy_init() failed\r\n");
    }
    curl_global_cleanup();
    pthread_mutex_unlock(&curl_lock);
    HET_LOGI("unlock\r\n");
    if(cJSON_IsString(content) && (content->valuestring != NULL)){
        pthread_mutex_lock(&curl_buf_lock); 
        memset(nls_openai_buf,0,sizeof(nls_openai_buf)); 
        strncpy(nls_openai_buf,content->valuestring,strlen(content->valuestring)>sizeof(nls_openai_buf)-1?sizeof(nls_openai_buf)-1:strlen(content->valuestring));
        pthread_mutex_unlock(&curl_buf_lock);
	    HET_LOGD("openai resp:%s\r\n", nls_openai_buf);
        in_query = RK_FALSE;
        if(autoGoto){
            res = speechSynthesizerPut(content->valuestring, RK_NULL);
        }
    }else{
        in_query = RK_FALSE;
    }
    // 清理JSON对象
    if(json){
        cJSON_Delete(json);
    }
    if(response_json){
        cJSON_Delete(response_json);
    }
    free(post_data);
    free(chunk.data);
    return res;
}
/**
 * @brief 语音识别
 */
int speechRecognizerPut(char *fileName,int autoGoto){
    char url[2048];
    int ret =-1;
    CURL *curl;
    CURLcode res;
    FILE *pcm_file;
    long file_size;
    char *file_data;
    MemoryStruct chunk;
    cJSON *result = NULL;
    cJSON *response_json = NULL;
    memset(url,0,sizeof(url));
    sprintf(url,"https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/asr?appkey=%s&token=%s&format=pcm&sample_rate=%d",
    ali_appKeyBuf,ali_tokenBuf,ali_sampleRate);
    HET_LOGI("url:%s\r\n",url);
    chunk.data = (char *)malloc(1);  // 初始内存分配
    chunk.data[0]='\0';
    chunk.size = 0;          // 没有数据

    // 打开PCM文件
    pcm_file = fopen(fileName, "rb");
    if (!pcm_file) {
        HET_LOGE("Failed to open PCM file");
        return -2;
    }
    // 获取文件大小
    fseek(pcm_file, 0, SEEK_END);
    file_size = ftell(pcm_file);
    fseek(pcm_file, 0, SEEK_SET);

    // 读取文件数据
    file_data = (char *)malloc(file_size);
    if (!file_data) {
        HET_LOGE("Failed to allocate memory");
        fclose(pcm_file);
        return -3;
    }
    fread(file_data, 1, file_size, pcm_file);
    fclose(pcm_file);
    HET_LOGD("lock\r\n");
    pthread_mutex_lock(&curl_lock);
    in_asr = RK_TRUE;
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if(curl) {
        // 设置目标URL
        curl_easy_setopt(curl, CURLOPT_URL, url);

        // 设置HTTP头部，请求Upgrade到WebSocket
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        //临时禁用ssl
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
        //curl_easy_setopt(curl, CURLOPT_CAINFO,"/userdata/curl_cacert.pem");
 
        // 设置连接超时时间
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
        // 设置POST请求
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);

        // 设置请求体
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, file_data);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, file_size);

        // 设置回调函数处理响应
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

        // 执行请求
        ret = curl_easy_perform(curl);

        // 检查请求是否成功
        if(ret != CURLE_OK){
            HET_LOGE("curl_easy_perform() failed: %s\r\n", curl_easy_strerror(res));
            ret =  -6;
        }else{
            HET_LOGD("buffer:%s\r\n",chunk.data);
            // 使用cJSON解析返回的数据
            response_json = cJSON_Parse(chunk.data);
            if (response_json == NULL) {
                HET_LOGE("Error parsing JSON response\r\n");
                ret = -4;
            } else {
                cJSON *status = cJSON_GetObjectItemCaseSensitive(response_json, "status");
                if (cJSON_IsNumber(status) && status->valueint == 20000000) {
                    result = cJSON_GetObjectItemCaseSensitive(response_json, "result");
                    if (cJSON_IsString(result) && (result->valuestring != NULL)) {
                        HET_LOGD("Result: %s\r\n", result->valuestring);
                        ret = 0;
                    }
                } else {
                    HET_LOGE("Status is not 20000000\r\n");
                    ret = -5;
                }
            }
        }
        // 清理cURL相关资源
        HET_LOGD("curl_slist_free_all\r\n");
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }else{
        HET_LOGE("curl_easy_init() failed\r\n");
    }
    curl_global_cleanup();
    in_asr = RK_FALSE;
    pthread_mutex_unlock(&curl_lock);
    HET_LOGI("unlock\r\n");
    if(ret == 0 && strlen(result->valuestring) > AGENT_STRLEN_MIN){
	    HET_LOGD("recognizer:%s\r\n", result->valuestring);
        pthread_mutex_lock(&curl_buf_lock);
        memset(nls_recognizer_buf,0,sizeof(nls_recognizer_buf));
        strncpy(nls_recognizer_buf,result->valuestring,strlen(result->valuestring)>sizeof(nls_recognizer_buf)-1?sizeof(nls_recognizer_buf)-1:strlen(result->valuestring));
        pthread_mutex_unlock(&curl_buf_lock);
        if(g_ctx.ai.s32loopCount ==-1){
            HET_LOGD("recognizer buf:%s\r\n",nls_recognizer_buf);
            #if 0
            // 不能直接调用，边播边识别只是为了识别和打断当前会话
            if(get_chat_stat() && autoGoto){
                if(get_chat_cloud()){
                    ret = openaiPut(result->valuestring,autoGoto);
                }else{
                    ret = clifeMicroAppToolChat(result->valuestring,0,autoGoto);
                    
                }
            }
            #endif
        }
    }
    // 清理JSON对象
    if(response_json){
        cJSON_Delete(response_json);
    }
    free(file_data);
    free(chunk.data);
    return ret;

}
